/*
 * 
 */
package com.yuanmei.stockeyes.charts;

import android.content.Context;
import android.graphics.Color;
import android.graphics.PointF;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.style.ForegroundColorSpan;
import android.util.Log;
import android.view.View;
import android.view.View.OnTouchListener;

import com.tictactec.ta.lib.Core;
import com.tictactec.ta.lib.MInteger;
import com.tictactec.ta.lib.RetCode;
import com.yuanmei.stockeyes.R;
import com.yuanmei.stockeyes.artifacts.Extensions;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import cn.limc.androidcharts.entity.DateValueEntity;
import cn.limc.androidcharts.entity.IStickEntity;
import cn.limc.androidcharts.entity.LineEntity;
import cn.limc.androidcharts.entity.ListChartData;
import cn.limc.androidcharts.entity.StickEntity;
import cn.limc.androidcharts.event.IDisplayCursorListener;
import cn.limc.androidcharts.view.MASlipStickChart;

//import android.util.Log;

public class TalibAmountChart implements ITalibChart {
    private final Core mTaLibCore = new Core();
    private MASlipStickChart mAmountChartView;
    private Context mContext;
    private static final String TAG = TalibAmountChart.class.getName();

    private int mAmountStickColor = Color.RED;
    private List<DateValueEntity> mAmountShortSmaDateValueList;
    private List<DateValueEntity> mAmountMediumSmaDateValueList;
    private List<DateValueEntity> mAmountLongSmaDateValueList;

    private LineEntity<DateValueEntity> mAmountShortSmaLineEntity;
    private LineEntity<DateValueEntity> mAmountMediumSmaLineEntity;
    private LineEntity<DateValueEntity> mAmountLongSmaLineEntity;

    private int mAmountShortPeriod  = 5;
    private int mAmountMediumPeriod = 10;
    private int mAmountLongPeriod   = 20;

    private String mAmountShortPeriodName;
    private String mAmountMediumPeriodName;
    private String mAmountLongPeriodName;

    private List<IStickEntity> mAmountEntityList;
    private int mTaIdxDataSetsBegin;
    private int mTaIdxDataSetsNumber;

    public TalibAmountChart(Context context) {
        mAmountChartView = new MASlipStickChart(context);
        //mAmountChartView.setColoredStickStyle(MASlipStickChart.DEFAULT_COLORED_STICK_STYLE_STROKE);
        TalibChartFactory.commonInitGridChart(mAmountChartView);
        TalibChartFactory.commonInitSlipStickChart(mAmountChartView);
        mContext = mAmountChartView.getContext();

        mAmountChartView.setStickFillColor(Color.TRANSPARENT);
        mAmountChartView.setStickBorderColor(mAmountStickColor);
        mAmountShortPeriodName   = mContext.getString(R.string.param_ma_short_period);
        mAmountMediumPeriodName  = mContext.getString(R.string.param_ma_medium_period);
        mAmountLongPeriodName    = mContext.getString(R.string.param_ma_long_period);
    }

    @Override
    public boolean reloadData(int dataLen,
                              float[] openPrices,
                              float[] highPrices,
                              float[] lowPrices,
                              float[] closePrices,
                              float[] volumes,
                              float[] amounts,
                              int[]   dates) {

        MInteger shortOutBegIdx    = new MInteger();
        MInteger shortOutNBElement = new MInteger();
        double[] shortOutSMA       = new double[dataLen];

        RetCode retCode = mTaLibCore.sma(0, amounts.length - 1, amounts,
                mAmountShortPeriod, shortOutBegIdx, shortOutNBElement, shortOutSMA);
        if (retCode != RetCode.Success) {
            Log.e(TAG, "Amount Chart mTaLibCore.SMA short calc error retCode="
                    + retCode);
            return false;
        }

        mAmountShortSmaDateValueList = new ArrayList<>();
        for (int i = 0; i < dataLen; i++) {
            if (i < shortOutBegIdx.value) {
                mAmountShortSmaDateValueList.add(new DateValueEntity(
                        (float) (shortOutSMA[0]), dates[i]));
            } else {
                int idx = i - shortOutBegIdx.value;
                mAmountShortSmaDateValueList.add(new DateValueEntity(
                        (float) (shortOutSMA[idx]), dates[i]));
            }
        }

        MInteger mediumOutBegIdx    = new MInteger();
        MInteger mediumOutNBElement = new MInteger();
        double[] mediumOutSMA       = new double[dataLen];

        retCode = mTaLibCore.sma(0, amounts.length - 1, amounts,
                mAmountMediumPeriod, mediumOutBegIdx, mediumOutNBElement, mediumOutSMA);
        if (retCode != RetCode.Success) {
            Log.e(TAG, "Amount Chart mTaLibCore.SMA medium calc error retCode="
                    + retCode);
            return false;
        }

        mAmountMediumSmaDateValueList = new ArrayList<>();
        for (int i = 0; i < dataLen; i++) {
            if (i < mediumOutBegIdx.value) {
                mAmountMediumSmaDateValueList.add(new DateValueEntity(
                        (float) (mediumOutSMA[0]), dates[i]));
            } else {
                int idx = i - mediumOutBegIdx.value;
                mAmountMediumSmaDateValueList.add(new DateValueEntity(
                        (float) (mediumOutSMA[idx]), dates[i]));
            }
        }

        MInteger longOutBegIdx    = new MInteger();
        MInteger longOutNBElement = new MInteger();
        double[] longOutSMA       = new double[dataLen];

        retCode = mTaLibCore.sma(0, amounts.length - 1, amounts,
                mAmountLongPeriod, longOutBegIdx, longOutNBElement, longOutSMA);
        if (retCode != RetCode.Success) {
            Log.e(TAG, "Amount Chart mTaLibCore.SMA long calc error retCode="
                    + retCode);
            return false;
        }

        mAmountLongSmaDateValueList = new ArrayList<>();
        for (int i = 0; i < dataLen; i++) {
            if (i < longOutBegIdx.value) {
                mAmountLongSmaDateValueList.add(new DateValueEntity(
                        (float) (longOutSMA[0]), dates[i]));
            } else {
                int idx = i - longOutBegIdx.value;
                mAmountLongSmaDateValueList.add(new DateValueEntity(
                        (float) (longOutSMA[idx]), dates[i]));
            }
        }
        
        List<LineEntity<DateValueEntity>> lines = new ArrayList<LineEntity<DateValueEntity>>();

        mAmountShortSmaLineEntity = new LineEntity<DateValueEntity>();
        mAmountShortSmaLineEntity.setTitle("MA" + mAmountShortPeriod);
        mAmountShortSmaLineEntity.setLineColor(Color.WHITE);
        mAmountShortSmaLineEntity.setLineData(mAmountShortSmaDateValueList);
        lines.add(mAmountShortSmaLineEntity);

        mAmountMediumSmaLineEntity = new LineEntity<DateValueEntity>();
        mAmountMediumSmaLineEntity.setTitle("MA" + mAmountMediumPeriod);
        mAmountMediumSmaLineEntity.setLineColor(Color.YELLOW);
        mAmountMediumSmaLineEntity.setLineData(mAmountMediumSmaDateValueList);
        lines.add(mAmountMediumSmaLineEntity);

        mAmountLongSmaLineEntity = new LineEntity<DateValueEntity>();
        mAmountLongSmaLineEntity.setTitle("MA" + mAmountLongPeriod);
        mAmountLongSmaLineEntity.setLineColor(Color.GREEN);
        mAmountLongSmaLineEntity.setLineData(mAmountLongSmaDateValueList);
        lines.add(mAmountLongSmaLineEntity);

        mAmountEntityList = new ArrayList<>();
        for (int i = 0; i < dataLen; i++) {
            mAmountEntityList.add(new StickEntity(amounts[i], 0, dates[i]));
        }

        mAmountChartView.setStickData(new ListChartData<>(mAmountEntityList));
        mAmountChartView.setLineData(lines);

        mTaIdxDataSetsBegin  = Math.max(shortOutBegIdx.value,
                Math.max(mediumOutBegIdx.value, longOutBegIdx.value));
        mTaIdxDataSetsNumber = Math.min(shortOutNBElement.value,
                Math.min(mediumOutNBElement.value, longOutNBElement.value));

        return true;
    }

    @Override
    public int getTaIndexNumber() {
        return mTaIdxDataSetsNumber;
    }

    @Override
    public String getTaIndexShortName() {
        return "AMOUNT";
    }

    @Override
    public String getTaIndexParms() {
        return  mAmountShortPeriod
                + "," + mAmountMediumPeriod
                + "," + mAmountLongPeriod;
    }

    @Override
    public Spanned getTaIndexDetail() {
        if (null == mAmountEntityList ||
                null == mAmountShortSmaDateValueList ||
                null == mAmountMediumSmaDateValueList ||
                null == mAmountLongSmaDateValueList
                ) {
            return new SpannableString("----");
        }

        int index = mAmountChartView.getSelectedIndex();

        IStickEntity    amountEntity = mAmountEntityList.get(index);
        DateValueEntity shortEntity  = mAmountShortSmaDateValueList.get(index);
        DateValueEntity meidumEntity = mAmountMediumSmaDateValueList.get(index);
        DateValueEntity longEntity   = mAmountLongSmaDateValueList.get(index);

        String AmountText = String.format(Locale.ENGLISH, "Amount:%s ",
                Extensions.fromValueToAbbreviation((float) amountEntity.getHigh()));

        String shortSmaText = String.format(Locale.ENGLISH, "MA%d:%s ",
                mAmountShortPeriod,
                Extensions.fromValueToAbbreviation((float) shortEntity.getValue()));
        String mediumSmaText = String.format(Locale.ENGLISH, "MA%d:%s ",
                mAmountMediumPeriod,
                Extensions.fromValueToAbbreviation((float) meidumEntity.getValue()));
        String longSmaText = String.format(Locale.ENGLISH, "MA%d:%s ",
                mAmountLongPeriod,
                Extensions.fromValueToAbbreviation((float) longEntity.getValue()));

//        String dateText = String.format(Locale.ENGLISH, "%d ", entity.getDate());

        String    finalString = AmountText + shortSmaText + mediumSmaText + longSmaText;
        Spannable sb          = new SpannableString(finalString);

        sb.setSpan(new ForegroundColorSpan(mAmountStickColor), finalString.indexOf(AmountText),
                finalString.indexOf(AmountText) + AmountText.length(), Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
        sb.setSpan(new ForegroundColorSpan(mAmountShortSmaLineEntity.getLineColor()),
                finalString.indexOf(shortSmaText),
                finalString.indexOf(shortSmaText) + shortSmaText.length(), Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
        sb.setSpan(new ForegroundColorSpan(mAmountMediumSmaLineEntity.getLineColor()),
                finalString.indexOf(mediumSmaText),
                finalString.indexOf(mediumSmaText) + mediumSmaText.length(), Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
        sb.setSpan(new ForegroundColorSpan(mAmountLongSmaLineEntity.getLineColor()),
                finalString.indexOf(longSmaText),
                finalString.indexOf(longSmaText) + longSmaText.length(), Spanned.SPAN_EXCLUSIVE_INCLUSIVE);

//        sb.setSpan(new ForegroundColorSpan(Color.GRAY), finalString.indexOf(dateText),
//                finalString.indexOf(dateText) + dateText.length(), Spanned.SPAN_EXCLUSIVE_INCLUSIVE);

        return (sb);
    }

    @Override
    public int getTaIndexBegin() {
        return mTaIdxDataSetsBegin;
    }

    @Override
    public View getChartView() {
        return mAmountChartView;
    }

    @Override
    public void setDisplayFrom(int from) {
        mAmountChartView.setDisplayFrom(from);
    }

    @Override
    public void setDisplayCrossXOnTouch(boolean displayCrossXOnTouch) {
        mAmountChartView.setDisplayCrossXOnTouch(displayCrossXOnTouch);
    }

    @Override
    public void setDisplayNumber(int number) {
        mAmountChartView.setDisplayNumber(number);
    }

    @Override
    public void setOnTouchListener(OnTouchListener l) {
        mAmountChartView.setOnTouchListener(l);
    }

    @Override
    public void setOnDisplayCursorListener(
            IDisplayCursorListener l) {
        mAmountChartView.setOnDisplayCursorListener(l);
    }

    @Override
    public PointF getTouchPoint() {
        return mAmountChartView.getTouchPoint();
    }

    @Override
    public void setTouchPoint(PointF touchPoint) {
        mAmountChartView.setTouchPoint(touchPoint);
    }

    @Override
    public void postInvalidate() {
        mAmountChartView.postInvalidate();
    }

    @Override
    public float getValidMiddleY() {
        return mAmountChartView.getValidMiddleY();
    }

    @Override
    public List<Map<String, Object>> getTaParamsList(){
        List<Map<String, Object>> outParamsList = new ArrayList<Map<String, Object>>();

        Map<String, Object> item = new HashMap<String, Object>();

        item = new HashMap<String, Object>();
        item.put(ITalibChart.ITaParamNameKey,  mAmountShortPeriodName);
        item.put(ITalibChart.ITaParamValueKey, mAmountShortPeriod);
        outParamsList.add(item);

        item = new HashMap<String, Object>();
        item.put(ITalibChart.ITaParamNameKey,  mAmountMediumPeriodName);
        item.put(ITalibChart.ITaParamValueKey, mAmountMediumPeriod);
        outParamsList.add(item);

        item = new HashMap<String, Object>();
        item.put(ITalibChart.ITaParamNameKey,  mAmountLongPeriodName);
        item.put(ITalibChart.ITaParamValueKey, mAmountLongPeriod);
        outParamsList.add(item);

        return outParamsList;
    }

    @Override
    public void setTaParams(Hashtable<String, Integer> inParms) {
        if (inParms.containsKey(mAmountShortPeriodName)
                && inParms.containsKey(mAmountMediumPeriodName)
                && inParms.containsKey(mAmountLongPeriodName)
                ) {
            mAmountShortPeriod   = inParms.get(mAmountShortPeriodName);
            mAmountMediumPeriod  = inParms.get(mAmountMediumPeriodName);
            mAmountLongPeriod    = inParms.get(mAmountLongPeriodName);
        }

    }
}
